﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Authentication;
using AWA.VAT.DbAccess.Excel;
using AWA.VAT.DbAccess.SQL;

namespace AWA.VAT.EmailApp.Models
{
    public class VATEmailModel
    {
        private string _rawMessage;

        #region Events
        public event EventHandler EmailingCompleted;
        private void RaiseEmailingCompleted()
        {
            EventHandler eh = EmailingCompleted;
            if (eh != null)
                eh(this, EventArgs.Empty);
        }

        public event EventHandler<EmailEventArgs> EmailFailed;
        private void RaiseEmailFailed(EmailEventArgs args)
        {
            EventHandler<EmailEventArgs> eh = EmailFailed;
            if (eh != null)
                eh(this, args);
        }

        public event EventHandler<EmailEventArgs> EmailSent;
        private void RaiseEmailSent(EmailEventArgs args)
        {
            EventHandler<EmailEventArgs> eh = EmailSent;
            if (eh != null)
                eh(this, args);
        }

        public event EventHandler<EmailEventArgs> EmailSkipped;
        private void RaiseEmailSkipped(EmailEventArgs args)
        {
            EventHandler<EmailEventArgs> eh = EmailSkipped;
            if (eh != null)
                eh(this, args);
        }

        public event EventHandler AuthenticationFailed;
        private void RaiseAuthenticationFailed()
        {
            EventHandler eh = AuthenticationFailed;
            if (eh != null)
                eh(this, EventArgs.Empty);
        }
        #endregion

        #region Constructor
        public VATEmailModel()
        {
            this._rawMessage = BuildRawMessage();
        } 
        #endregion

        public void SendEmails(ExcelDataConnector _connector)
        {
            Emailer emailer = new Emailer();

            foreach (PersonInfo person in _connector.GetInfo())
            {
                try
                {
                    if (!person.Sent)
                    {
                        emailer.SendEmail(person.Email, Configuration.MessageSubject,
                            String.Format(_rawMessage, person.RealName, person.Address));
                        RaiseEmailSent(new EmailEventArgs(person));
                        _connector.MarkAsSent(person.Email);
                    }
                    else
                    {
                        RaiseEmailSkipped(new EmailEventArgs(person));
                    }
                }
                catch (AuthenticationException)
                {
                    RaiseAuthenticationFailed();
                    break;
                }
                catch (Exception)
                {
                    RaiseEmailFailed(new EmailEventArgs(person));
                }
            }
            RaiseEmailingCompleted();
        }

        public void SendEmails(SQLDataConnector _connector)
        {
            // TODO: 
            Emailer emailer = new Emailer();

            foreach (Attendance attendance in _connector.GetAttendees(Configuration.Year))
            {
                EmailEventArgs args = new EmailEventArgs(new PersonInfo()
                    {
                        RealName = attendance.Editor.RealName,
                        Email = attendance.Editor.Email
                    });

                try
                {
                    if (!attendance.EmailSent)
                    {
                        string address = String.Format("{0}\n{1}, {2} {3}\n{4}",
                            attendance.Editor.StreetAddress,
                            attendance.Editor.City,
                            attendance.Editor.Region.RegionAbbrev,
                            attendance.Editor.PostalCode,
                            attendance.Editor.Country);
                        emailer.SendEmail(attendance.Editor.Email, Configuration.MessageSubject,
                            String.Format(_rawMessage, attendance.Editor.RealName, address));
                        RaiseEmailSent(args);
                        attendance.EmailSent = true;
                        _connector.MarkAsSent(attendance);
                    }
                    else
                    {
                        RaiseEmailSkipped(args);
                    }
                }
                catch (AuthenticationException)
                {
                    RaiseAuthenticationFailed();
                    break;
                }
                catch (Exception)
                {
                    RaiseEmailFailed(args);
                }
            }
            RaiseEmailingCompleted();
        }

        public string BuildRawMessage()
        {
            StringBuilder theMessage = new StringBuilder();
            theMessage.AppendLine(Configuration.MessageGreeting);
            theMessage.AppendLine();
            theMessage.AppendLine(Configuration.MessagePara1);
            theMessage.AppendLine();
            theMessage.AppendLine(Configuration.MessageInfoOnFile);
            theMessage.AppendLine("{0}"); // name in DB
            theMessage.AppendLine("{1}"); // address in DB
            theMessage.AppendLine();
            theMessage.AppendLine(Configuration.MessageCheckIn);
            theMessage.AppendLine();
            theMessage.AppendLine(Configuration.MessageClosing);
            theMessage.AppendLine(Configuration.MessageSenderName);
            theMessage.AppendLine(Configuration.MessageSenderTitle);

            return theMessage.ToString();
        }
    }
}
